﻿/****************************************************************************************************
	Copyright (C) 2010 RapidWebDev Organization (http://rapidwebdev.org)
	Author: Eunge, Legal Name: Jian Liu, Email: eunge.liu@RapidWebDev.org

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ****************************************************************************************************/

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;

namespace RapidWebDev.SearchIndex
{
	internal sealed class LuceneFields
	{
		internal const string DocumentId = "LuceneFields_Id";
		internal const string ApplicationId = "LuceneFields_ApplicationId";
		internal const string DocumentType = "LuceneFields_Type";
		internal const string StemmingLanguage = "LuceneFields_StemmingLanguage";
		internal const string Content = "LuceneFields_Content";
		internal const string UpdatedOn = "LuceneFields_UpdatedOn";
		internal const string AttachmentsCount = "LuceneFields_AttachmentsCount";
		internal const string SortableFieldPrefixName = "___Sortable";

		private static readonly HashSet<string> CommonFields = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
		{
			DocumentId, 
			ApplicationId, 
			DocumentType,
			StemmingLanguage,
			Content,
			UpdatedOn,
			AttachmentsCount
		};

		/// <summary>
		/// Check whether the field name is common field.
		/// </summary>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		internal static bool IsCommonField(string fieldName)
		{
			if (fieldName == null) return true;
			return CommonFields.Contains(fieldName);
		}

		/// <summary>
		/// Check whether the field name is predefined.
		/// </summary>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		internal static bool IsPredefinedField(string fieldName)
		{
			if (fieldName == null) return true;
			if (CommonFields.Contains(fieldName)) return true;
			if (IsFieldTypeField(fieldName)) return true;
			if (IsAttachmentField(fieldName)) return true;
			if (IsSortableFieldName(fieldName)) return true;

			return false;
		}

		/// <summary>
		/// {FieldName}___FieldType.
		/// </summary>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		internal static string FieldType(string fieldName)
		{
			return fieldName + "___FieldType";
		}

		/// <summary>
		/// Check whether the field name is used for field type.
		/// </summary>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		internal static bool IsFieldTypeField(string fieldName)
		{
			if (fieldName == null) return false;
			return fieldName.EndsWith("___FieldType", StringComparison.Ordinal);
		}

		/// <summary>
		/// Get original field name of the field type field.
		/// If the argument is not a field type field, the method returns the argument directly.
		/// </summary>
		/// <param name="fieldTypeFieldName"></param>
		/// <returns></returns>
		internal static string GetOriginalFieldNameOfFieldTypeField(string fieldTypeFieldName)
		{
			if (!IsFieldTypeField(fieldTypeFieldName))
				return fieldTypeFieldName;

			return fieldTypeFieldName.Substring(0, fieldTypeFieldName.Length - 12);
		}

		/// <summary>
		/// Attachment{index}_Id
		/// </summary>
		/// <param name="index"></param>
		/// <returns></returns>
		internal static string AttachmentIdField(int index)
		{
			return "Attachment___" + index.ToString(CultureInfo.InvariantCulture) + "_Id";
		}

		/// <summary>
		/// Attachment{index}_Name
		/// </summary>
		/// <param name="index"></param>
		/// <returns></returns>
		internal static string AttachmentNameField(int index)
		{
			return "Attachment___" + index.ToString(CultureInfo.InvariantCulture) + "_Name";
		}

		/// <summary>
		/// Returns true if the field is an attachment name field.
		/// </summary>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		internal static bool IsAttachmentNameField(string fieldName)
		{
			if (string.IsNullOrEmpty(fieldName)) return false;
			return fieldName.StartsWith("Attachment___", StringComparison.OrdinalIgnoreCase) && fieldName.EndsWith("_Name", StringComparison.OrdinalIgnoreCase);
		}

		/// <summary>
		/// Attachment{index}_SharedPath
		/// </summary>
		/// <param name="index"></param>
		/// <returns></returns>
		internal static string AttachmentSharedPathField(int index)
		{
			return "Attachment___" + index.ToString(CultureInfo.InvariantCulture) + "_SharedPath";
		}

		/// <summary>
		/// Check whether the field name is used for attachments.
		/// </summary>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		internal static bool IsAttachmentField(string fieldName)
		{
			if (fieldName == null) return false;
			return fieldName.StartsWith("Attachment___", StringComparison.Ordinal);
		}

		/// <summary>
		/// Get the sortable field name for the field. 
		/// </summary>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		internal static string SortableFieldName(string fieldName)
		{
			return fieldName + SortableFieldPrefixName;
		}

		/// <summary>
		/// Check the field name is a sortable field name.
		/// </summary>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		internal static bool IsSortableFieldName(string fieldName)
		{
			if (fieldName == null) return false;
			return fieldName.EndsWith(SortableFieldPrefixName, StringComparison.Ordinal);
		}

		/// <summary>
		/// Get original field name of the sortable field.
		/// If the argument is not a sortable field, the method returns the argument directly.
		/// </summary>
		/// <param name="sortableFieldName"></param>
		/// <returns></returns>
		internal static string GetOriginalFieldNameOfSortableField(string sortableFieldName)
		{
			if (!IsSortableFieldName(sortableFieldName))
				return sortableFieldName;

			return sortableFieldName.Substring(0, sortableFieldName.Length - 11);
		}
	}
}
